home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Kant Generator Pro 1.2 / src / Shell ƒ / prefs.c < prev    next >
C/C++ Source or Header  |  1995-02-02  |  12KB  |  436 lines

  1. #include "program globals.h"
  2. #include "prefs.h"
  3. #include "help.h"
  4. #include "dialogs.h"
  5. #include "environment.h"
  6. #include "util.h"
  7. #include "window layer.h"
  8. #include <Folders.h>
  9.  
  10. #define        PREFS_FILE_NAME            "\pKant Generator Pro prefs"
  11. #define        PREFS_TYPE                'pref'
  12. // CREATOR is #defined in "program globals.h"
  13. #define        PREFS_HEADER_VERSION    6
  14.  
  15. Str255            gMyName;
  16. Str255            gMyOrg;
  17.  
  18. typedef struct
  19. {
  20.     long            fileID;
  21.     short            maintopic;
  22.     short            subtopic;
  23.     
  24.     char            regname[40];
  25.     char            regorg[40];
  26.     Boolean            alwaysResolve;
  27.     Boolean            useDefault;
  28.     short            speedDelay;
  29.     Boolean            dynamicScroll;
  30.     Boolean            startFromTop;
  31.     Boolean            ignoreCase;
  32.     Boolean            showAllRefs;
  33.     Boolean            iconifyMenus;
  34.     Boolean            showMessageBox;
  35.     Boolean            showToolbar;
  36.     Boolean            unused;
  37.     Str255            findStr;
  38.     Str255            replaceStr;
  39.     FSSpec            moduleFS;
  40. } PrefStruct;
  41.  
  42. /* internal globals for use in prefs.c only */
  43. static long            gFileID;
  44. static Boolean        gCanSavePrefs;
  45. static PrefStruct    thePrefs;
  46. static long            gPrefsFilePos;
  47.  
  48. /*-----------------------------------------------------------------------------------*/
  49. /* internal stuff for prefs.c                                                        */
  50.  
  51. static    enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  52. static    enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  53. static    void ClosePrefsFile(short prefsFileID);
  54. static    enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  55. static    enum PrefErrorTypes SavePrefs(short prefsFileID);
  56. static    enum PrefErrorTypes CheckVersion(short prefsFileID);
  57. static    enum PrefErrorTypes GetFileID(void);
  58. static    enum PrefErrorTypes CheckFileID(void);
  59. static    enum PrefErrorTypes Virgin(short prefsFileID);
  60. static    void DefaultPrefs(void);
  61. static    void CopyGlobalsToPrefs(void);
  62. static    void CopyPrefsToGlobals(void);
  63. static    void GetRegistration(void);
  64.  
  65. void SaveThePrefs(void)
  66. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  67. {
  68.     short            prefsFileID;
  69.     
  70.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  71.     {
  72.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  73.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  74.         SavePrefs(prefsFileID);            /* save prefs to disk */
  75.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  76.     }
  77. }
  78.  
  79. enum PrefErrorTypes PreferencesInit(void)
  80. {
  81.     short            prefsFileID;
  82.     enum PrefErrorTypes        err;
  83.     
  84.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  85.     err=GetFileID();        /* get application file ID */
  86.     if (err!=prefs_allsWell)    /* screwed up already?!? */
  87.         return err;
  88.     
  89.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  90.     if (err!=prefs_allsWell)
  91.     {
  92.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  93.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  94.         return err;
  95.     }
  96.     
  97.     err=CheckVersion(prefsFileID);        /* check prefs version */
  98.     if (err!=prefs_allsWell)
  99.     {
  100.         ClosePrefsFile(prefsFileID);
  101.         return err;
  102.     }
  103.     
  104.     GetFPos(prefsFileID, &gPrefsFilePos);
  105.     gPrefsFilePos-=sizeof(thePrefs);
  106.     do
  107.     {
  108.         gPrefsFilePos+=sizeof(thePrefs);
  109.         err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  110.         if (err==prefs_noMorePrefsErr)        /* or not */
  111.             return (Virgin(prefsFileID));    /* can't find our file ID, it's our first time */
  112.         
  113.         if (err!=prefs_allsWell)            /* any other error, just abort */
  114.         {
  115.             ClosePrefsFile(prefsFileID);
  116.             return err;
  117.         }
  118.         
  119.         err=CheckFileID();                    /* check file ID of current prefs struct */
  120.     }
  121.     while (err==prefs_IDNotMatchErr);
  122.     
  123.     CopyPrefsToGlobals();                    /* copy prefs struct to program globals */
  124.     ClosePrefsFile(prefsFileID);            /* close prefs file */
  125.     
  126.     return prefs_allsWell;                    /* piece o' cake */
  127. }
  128.  
  129. void PrefsError(enum PrefErrorTypes err)
  130. {
  131.     Str255            tempStr;
  132.     
  133.     switch (err)
  134.     {
  135.         case prefs_diskReadErr:
  136.         case prefs_diskWriteErr:
  137.         case prefs_cantCreatePrefsErr:
  138.         case prefs_cantOpenPrefsErr:
  139.         case prefs_versionNotSupportedErr:
  140.             RemoveHilitePatch();
  141.             DefaultPrefs();                    /* use default prefs if error */
  142.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  143.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  144.             ParamText(tempStr, "\p", "\p", "\p");
  145.             PositionDialog('ALRT', largeAlert);
  146.             StopAlert(largeAlert, 0L);        /* display error alert */
  147.             InstallHilitePatch();
  148.             break;
  149.         default:
  150.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  151.             break;
  152.     }
  153. }
  154.  
  155. static    enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  156. {
  157.     short            thisFile;
  158.     Boolean            newPrefs;
  159.     unsigned char    *name=PREFS_FILE_NAME;
  160.     OSErr            isHuman;
  161.     short            vRefNum;
  162.     long            dirID;
  163.     FSSpec            prefsFile;
  164.     
  165.     newPrefs=FALSE;
  166.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  167.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  168.     
  169.     if (isHuman!=noErr)        /* screwed up already?!? */
  170.         return prefs_cantOpenPrefsErr;
  171.     
  172.     isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  173.     if (isHuman!=noErr)
  174.     {
  175.         if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  176.         {
  177.             isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  178.             if (isHuman!=noErr)                                        /* or not */
  179.                 return prefs_cantCreatePrefsErr;
  180.             newPrefs=TRUE;        /* signal that prefs file is new */
  181.         }
  182.         else return prefs_cantOpenPrefsErr;
  183.     }
  184.     isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  185.     *prefsFileID=thisFile;        /* store file reference number */
  186.     if (isHuman!=noErr)
  187.         return prefs_cantOpenPrefsErr;
  188.     
  189.     if (newPrefs)
  190.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  191.     
  192.     return prefs_allsWell;
  193. }
  194.  
  195. static    enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  196. /* this writes the prefs version number to the newly created prefs file, so we can
  197.    tell if the prefs file was created by a later version of the program and is
  198.    therefore in a format that we don't support -- forward compatability!  what
  199.    a concept! */
  200. {
  201.     long            count;
  202.     short            temp;
  203.     
  204.     gPrefsFilePos=2L;
  205.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  206.         return prefs_diskWriteErr;
  207.     
  208.     SetFPos(prefsFileID, 1, 0L);
  209.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  210.     count=2L;
  211.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  212.         return prefs_diskWriteErr;        
  213.     
  214.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  215. }
  216.  
  217. static    void ClosePrefsFile(short prefsFileID)
  218. {
  219.     FSClose(prefsFileID);                /* close file on disk */
  220.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  221. }
  222.  
  223. static    enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  224. {
  225.     OSErr        isHuman;
  226.     long        count;
  227.     
  228.     count=sizeof(thePrefs);
  229.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  230.     if (isHuman==eofErr)    /* no more left */
  231.         return prefs_noMorePrefsErr;
  232.     if (isHuman!=noErr)        /* some other error */
  233.         return prefs_diskReadErr;
  234.     
  235.     return prefs_allsWell;
  236. }
  237.  
  238. static    enum PrefErrorTypes SavePrefs(short prefsFileID)
  239. {
  240.     long        oldEOF;
  241.     long        count;
  242.     
  243.     GetEOF(prefsFileID, &oldEOF);
  244.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  245.     {
  246.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  247.             return prefs_diskWriteErr;
  248.     }
  249.     
  250.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  251.     count=sizeof(thePrefs);
  252.     /* write prefs struct and return appropriate error code */
  253.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  254.         prefs_diskWriteErr : prefs_allsWell;
  255. }
  256.  
  257. static    enum PrefErrorTypes CheckVersion(short prefsFileID)
  258. {
  259.     OSErr        isHuman;
  260.     long        count;
  261.     short            temp;
  262.     
  263.     count=2L;
  264.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  265.     if (isHuman!=noErr)
  266.         return prefs_diskReadErr;
  267.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  268.         return prefs_versionNotSupportedErr;
  269.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  270.         return SetupNewPrefsFile(prefsFileID);
  271.     
  272.     return prefs_allsWell;
  273. }
  274.  
  275. static    enum PrefErrorTypes GetFileID(void)
  276. {
  277.     ParamBlockRec    pb;
  278.     
  279.     pb.fileParam.ioCompletion=0L;
  280.     pb.fileParam.ioNamePtr=LMGetCurApName();
  281.     pb.fileParam.ioVRefNum=0;
  282.     pb.fileParam.ioFVersNum=0;
  283.     pb.fileParam.ioFDirIndex=0;
  284.     if (PBGetFInfo(&pb, FALSE)!=noErr)
  285.         return prefs_diskReadErr;
  286.     
  287.     gFileID=pb.fileParam.ioFlNum;
  288.     
  289.     return prefs_allsWell;
  290. }
  291.  
  292. static    enum PrefErrorTypes CheckFileID(void)
  293. {
  294.     /* compare file ID in current prefs struct to application's file ID */
  295.     return (thePrefs.fileID==gFileID) ? prefs_allsWell : prefs_IDNotMatchErr;
  296. }
  297.  
  298. static    enum PrefErrorTypes Virgin(short prefsFileID)
  299. {
  300.     enum PrefErrorTypes    err;
  301.     
  302.     DefaultPrefs();
  303.     CopyGlobalsToPrefs();
  304.     err=SavePrefs(prefsFileID);
  305.     if (err!=prefs_allsWell)
  306.         return err;
  307.     GetRegistration();
  308.     CopyGlobalsToPrefs();
  309.     err=SavePrefs(prefsFileID);
  310.     
  311.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  312. }
  313.  
  314. static    void DefaultPrefs(void)
  315. {
  316.     unsigned char        *bob="\pBob";
  317.     
  318.     gMainTopicShowing=gSubTopicShowing=0;
  319.     
  320.     Mymemcpy((Ptr)gMyName, (Ptr)bob, bob[0]+1);
  321.     gMyOrg[0]=0x00;
  322.     
  323.     gAlwaysResolve=TRUE;
  324.     gSpeedDelay=0;
  325.     gUseDefault=TRUE;
  326.     gModuleFS.name[0]=0x00;
  327.     gDynamicScroll=TRUE;
  328.     gIgnoreCase=TRUE;
  329.     gStartFromTop=TRUE;
  330.     Mymemset((Ptr)gFindString, 0, 256);
  331.     Mymemset((Ptr)gReplaceString, 0, 256);
  332.     gShowAllRefs=TRUE;
  333.     gIconifyMenus=FALSE;
  334.     gShowMessageBox=TRUE;
  335.     gShowToolbar=TRUE;
  336. }
  337.  
  338. static    void CopyGlobalsToPrefs(void)
  339. {
  340.     Mymemset((Ptr)(&thePrefs), 0, sizeof(thePrefs));
  341.     if (gMyName[0]>0x27)
  342.         gMyName[0]=0x27;
  343.     if (gMyOrg[0]>0x27)
  344.         gMyOrg[0]=0x27;
  345.     Mymemcpy((Ptr)thePrefs.regname, (Ptr)gMyName, gMyName[0]+1);
  346.     Mymemcpy((Ptr)thePrefs.regorg, (Ptr)gMyOrg, gMyOrg[0]+1);
  347.     thePrefs.maintopic=gMainTopicShowing;
  348.     thePrefs.subtopic=gSubTopicShowing;
  349.     thePrefs.fileID=gFileID;
  350.     
  351.     thePrefs.alwaysResolve=gAlwaysResolve;
  352.     thePrefs.speedDelay=gSpeedDelay;
  353.     thePrefs.useDefault=gUseDefault;
  354.     thePrefs.moduleFS=gModuleFS;
  355.     thePrefs.dynamicScroll=gDynamicScroll;
  356.     thePrefs.startFromTop=gStartFromTop;
  357.     thePrefs.ignoreCase=gIgnoreCase;
  358.     Mymemcpy((Ptr)thePrefs.findStr, gFindString, 256);
  359.     Mymemcpy((Ptr)thePrefs.replaceStr, gReplaceString, 256);
  360.     thePrefs.showAllRefs=gShowAllRefs;
  361.     thePrefs.iconifyMenus=gIconifyMenus;
  362.     thePrefs.showMessageBox=gShowMessageBox;
  363.     thePrefs.showToolbar=gShowToolbar;
  364. }
  365.  
  366. static    void CopyPrefsToGlobals(void)
  367. {
  368.     Mymemcpy((Ptr)gMyName, (Ptr)thePrefs.regname, thePrefs.regname[0]+1);
  369.     Mymemcpy((Ptr)gMyOrg, (Ptr)thePrefs.regorg, thePrefs.regorg[0]+1);
  370.     gMainTopicShowing=thePrefs.maintopic;
  371.     gSubTopicShowing=thePrefs.subtopic;
  372.     
  373.     gAlwaysResolve=thePrefs.alwaysResolve;
  374.     gSpeedDelay=thePrefs.speedDelay;
  375.     gUseDefault=thePrefs.useDefault;
  376.     gModuleFS=thePrefs.moduleFS;
  377.     gDynamicScroll=thePrefs.dynamicScroll;
  378.     gStartFromTop=thePrefs.startFromTop;
  379.     gIgnoreCase=thePrefs.ignoreCase;
  380.     gShowAllRefs=thePrefs.showAllRefs;
  381.     Mymemcpy((Ptr)gFindString, (Ptr)thePrefs.findStr, 256);
  382.     Mymemcpy((Ptr)gReplaceString, (Ptr)thePrefs.replaceStr, 256);
  383.     gIconifyMenus=thePrefs.iconifyMenus;
  384.     gShowMessageBox=thePrefs.showMessageBox;
  385.     gShowToolbar=thePrefs.showToolbar;
  386. }
  387.  
  388. static    void GetRegistration(void)
  389. {
  390.     DialogPtr        theDlog;
  391.     short            itemSelected = 0;
  392.     short            newleft;
  393.     short            newtop;
  394.     short            itemType;
  395.     Handle            item;
  396.     Rect            box;
  397.     ModalFilterUPP    procFilter=NewModalFilterProc(OneButtonFilter);
  398.     UserItemUPP        userUPP=NewUserItemProc(OutlineDefaultButton);
  399.     
  400.     theDlog = GetNewDialog(131, 0L, (WindowPtr)-1L);
  401.     newleft = qd.screenBits.bounds.left + (((qd.screenBits.bounds.right -
  402.                 qd.screenBits.bounds.left) - (theDlog->portRect.right -
  403.                 theDlog->portRect.left)) / 2);
  404.     newtop = qd.screenBits.bounds.top + (((qd.screenBits.bounds.bottom -
  405.                 qd.screenBits.bounds.top) - (theDlog->portRect.bottom -
  406.                 theDlog->portRect.top)) / 2);
  407.     if(newtop < 15)
  408.         newtop = 15;
  409.     GetDItem(theDlog, 1, &itemType, &item, &box);
  410.     InsetRect(&box, -4, -4);
  411.     SetDItem(theDlog, 8, userItem, (Handle)userUPP, &box);
  412.     ParamText(APPLICATION_NAME, "\p", "\p", "\p");
  413.     
  414.     MoveWindow(theDlog, newleft, newtop, TRUE);
  415.     ShowWindow(theDlog);
  416.     while (itemSelected != 1)
  417.     {
  418.         ModalDialog(procFilter, &itemSelected);
  419.     }
  420.     GetDItem(theDlog,4,&itemType,&item,&box);
  421.     GetIText(item,gMyName);
  422.     
  423.     GetDItem(theDlog,5,&itemType,&item,&box);
  424.     GetIText(item,gMyOrg);
  425.  
  426.     if (gMyName[0]==0x00)
  427.         DefaultPrefs();
  428.  
  429.     HideWindow(theDlog);
  430.     DisposeDialog(theDlog);
  431.     DisposeRoutineDescriptor(procFilter);
  432.     DisposeRoutineDescriptor(userUPP);
  433.     
  434.     gIsVirgin=TRUE;
  435. }
  436.